package com.jdzy.student.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jdzy.common.constants.CommonConstants;
import com.jdzy.common.constants.CopyrightConstants;
import com.jdzy.common.exception.DeleteException;
import com.jdzy.model.common.dtos.PageRequestDto;
import com.jdzy.model.common.vos.PageResult;
import com.jdzy.model.common.vos.Result;
import com.jdzy.model.student.dtos.CopyrightDeleteDto;
import com.jdzy.model.student.dtos.CopyrightDto;
import com.jdzy.model.student.dtos.CopyrightRearchDto;
import com.jdzy.model.student.pojos.Copyright;
import com.jdzy.model.student.pojos.CopyrightOwner;
import com.jdzy.model.student.vos.CopyrightVo;
import com.jdzy.student.mapper.CopyrightMapper;
import com.jdzy.student.mapper.CopyrightOwnerMapper;
import com.jdzy.student.service.CopyrightService;
import com.jdzy.utils.common.ParseToListOrStringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.*;

@Service
@Slf4j
public class CopyrightServiceImpl extends ServiceImpl<CopyrightMapper, Copyright> implements CopyrightService {

    @Autowired
    private CopyrightMapper copyrightMapper;

    @Autowired
    private CopyrightOwnerMapper copyrightOwnerMapper;


    /**
     * 根据学号获取其著作权
     *
     * @param stuId
     * @param page
     * @param size
     * @param copyrightRearchDto
     * @return
     */
    @Override
    public Result getCopyrightByStuId(String stuId, Integer page, Integer size, CopyrightRearchDto copyrightRearchDto) {
        //1、检查参数
        if(StringUtils.isBlank(stuId)){
            return Result.error(CommonConstants.PARAM_REQUIRE);
        }
        //设置分页
        PageRequestDto pageRequestDto=new PageRequestDto(page,size);
        pageRequestDto.checkParam();
        //分页查询
        IPage iPage=new Page(pageRequestDto.getPage(),pageRequestDto.getSize());

        //2.1、条件查询
        LambdaQueryWrapper<Copyright> copyrightLambdaQueryWrapper = Wrappers.<Copyright>lambdaQuery()
                .eq(Copyright::getStuId, stuId)
                .like(StringUtils.isNotBlank(copyrightRearchDto.getRegistrationNumber()),Copyright::getRegistrationNumber,copyrightRearchDto.getRegistrationNumber())
                //大于等于创建时间之后
                .ge(copyrightRearchDto.getCreateCopyrightTime()!=null,Copyright::getCreateCopyrightTime,copyrightRearchDto.getCreateCopyrightTime())
                .like(StringUtils.isNotBlank(copyrightRearchDto.getCopyrightName()),Copyright::getCopyrightName,copyrightRearchDto.getCopyrightName())
                .eq(copyrightRearchDto.getCopyrightStatus()!=null,Copyright::getCopyrightStatus,copyrightRearchDto.getCopyrightStatus())
                //在有限时间之前(小于等于有限时间)
                .le(copyrightRearchDto.getExpirationTime()!=null,Copyright::getExpirationTime,copyrightRearchDto.getExpirationTime()
                );

        //2.2、 若是查找 进行将字符串copyrightOwnerStr转换为List
        List<String> copyrightOwners = ParseToListOrStringUtils
                .parseToListWithString(copyrightRearchDto.getCopyrightOwnerStr(), CopyrightConstants.COPYRIGHT_SPILT);
        //从copyrightOwner根据OwnerStr姓名精确查找获取到copyright的id号
        List<Long> copyrightIdList = copyrightOwnerMapper.getCopyrightIdListByOwnerName(stuId, copyrightOwners);
        //2.3、此时根据拥有者表找到了对应的copyrightId  此时查询拥有者就是精确查找
        /*
        当输入的查找人字符串不为空且没有找到  则直接返回空(注意  这里不能约掉 这里必须进行这个判断  因为当copyrightIdList为空 默认就是不在意这条条件了)
        所以这行非常重要
         */
        if(StringUtils.isNotBlank(copyrightRearchDto.getCopyrightOwnerStr())
                && copyrightIdList==null || copyrightIdList.size()==0){
            //封装分页信息
            PageResult pageResult=new PageResult(pageRequestDto.getPage(),pageRequestDto.getSize(),iPage.getTotal());
            return pageResult;
        }

        // 加入到条件查询中
        copyrightLambdaQueryWrapper.in(copyrightIdList!=null && copyrightIdList.size()!=0
                ,Copyright::getId,copyrightIdList);


        //3、进行分页查询
        IPage selectPage = copyrightMapper.selectPage(iPage,copyrightLambdaQueryWrapper);
        List<Copyright> copyrights = selectPage.getRecords();

        //进行数据拷贝
        List<CopyrightVo> copyrightVos=new ArrayList<>();
        for (Copyright copyright:copyrights) {
            CopyrightVo copyrightVo=new CopyrightVo();
            BeanUtils.copyProperties(copyright,copyrightVo);
            //4、从copyRight根据copyrightid获取到参与者
            List<String> copyrightOwnerNameList = copyrightOwnerMapper.getCopyrightOwnerName(copyright.getId());
            //5、转换成字符串形式
            String copyrightOwnerNameStr = ParseToListOrStringUtils
                    .parseToString(copyrightOwnerNameList, CopyrightConstants.COPYRIGHT_SPILT);
            //6、加入到vo类中
            copyrightVo.setCopyrightOwnerStr(copyrightOwnerNameStr);
            copyrightVos.add(copyrightVo);
        }

        //3、封装分页信息
        PageResult pageResult=new PageResult(pageRequestDto.getPage(),pageRequestDto.getSize(),iPage.getTotal());
        pageResult.setData(copyrightVos);
        return pageResult;
    }

    /**
     * 删除著作权信息
     * @param stuId
     * @param copyrightDeleteDto
     * @return
     */
    @Override
    public Result deleteCopyright(String stuId,  CopyrightDeleteDto copyrightDeleteDto) {
        //1、检查参数
        if(StringUtils.isBlank(stuId) || copyrightDeleteDto==null || copyrightDeleteDto.getCopyrightIds().isEmpty()){
            return Result.error(CommonConstants.PARAM_REQUIRE);
        }
        //2、进行操作
        synchronized ("deleteCopyright"+CommonConstants.LOCK_INDEX+ stuId){
            //2.1、判断数据库中有没有这些数据
            List<Copyright> copyrights = copyrightMapper.selectList(Wrappers.<Copyright>lambdaUpdate()
                    .eq(Copyright::getStuId, stuId)
                    .in(Copyright::getId, copyrightDeleteDto.getCopyrightIds()));
            if(copyrights.size()!=copyrightDeleteDto.getCopyrightIds().size()){
                //数据数量对不上
                return Result.error(CommonConstants.DATASOURCE_IS_NULL);
            }
            //2、1进行删除数据
            int delete = copyrightMapper.delete(Wrappers.<Copyright>lambdaUpdate()
                    .eq(Copyright::getStuId, stuId)
                    .in(Copyright::getId, copyrightDeleteDto.getCopyrightIds())
                    );
            try {
                if(delete!=copyrightDeleteDto.getCopyrightIds().size()){
                    //删除数据量对不上  报错 回滚事务
                    throw new DeleteException();
                }
                //删除拥有者表信息
                copyrightOwnerMapper.delete(Wrappers.<CopyrightOwner>lambdaQuery()
                        .in(copyrightDeleteDto.getCopyrightIds().size()!=0,CopyrightOwner::getCopyrightId,copyrightDeleteDto.getCopyrightIds())
                        .eq(CopyrightOwner::getStuId,stuId)
                );
            }catch (DeleteException deleteException){
                //手动回滚事务
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                log.error("deleteCopyright---->删除数据量对不上");
                return Result.error(CommonConstants.DELETE_FAIL);
            }
        }
        return Result.success();
    }

    /**
     * 保存Copyright信息
     * @param copyrightDto
     * @return
     */
    @Override
    public Result saveCopyright(CopyrightDto copyrightDto) {
        //1、检查参数
        if(copyrightDto==null || StringUtils.isBlank(copyrightDto.getStuId())
                || StringUtils.isBlank(copyrightDto.getCopyrightName())){
            return Result.error(CommonConstants.PARAM_REQUIRE);
        }
        //2、进行参数拷贝
        Copyright copyright=new Copyright();
        BeanUtils.copyProperties(copyrightDto,copyright);
        //3、进行插入数据库
        int insert = copyrightMapper.insert(copyright);
        if(insert==0){
            return Result.error(CommonConstants.INSERT_FAIL);
        }
        //4、插入到拥有者表中
        List<String> CopyrightOwners = ParseToListOrStringUtils.parseToListWithString(copyrightDto.getCopyrightOwnerStr()
                , CopyrightConstants.COPYRIGHT_SPILT);
//        List<CopyrightOwner> copyrightOwnerList=new ArrayList<>();
        for (String copyrightOwnerStr : CopyrightOwners) {
            CopyrightOwner copyrightOwner=new CopyrightOwner();
            copyrightOwner.setStuId(copyrightDto.getStuId());
            copyrightOwner.setCopyrightId(copyright.getId());
            copyrightOwner.setCopyrightOwnerName(copyrightOwnerStr);

//            copyrightOwnerList.add(copyrightOwner);
            copyrightOwnerMapper.insert(copyrightOwner);
        }
        return Result.success();
    }

    /**
     * 修改Copyright信息
     * @param copyrightDto
     * @return
     */
    @Override
    public Result updateCopyright(CopyrightDto copyrightDto) {
        //1、检查参数
        if(copyrightDto==null || copyrightDto.getId()==null || StringUtils.isBlank(copyrightDto.getStuId())){
            return Result.error(CommonConstants.PARAM_REQUIRE);
        }
        //2、查询数据库中有无该数据
        Copyright copyright = copyrightMapper.selectOne(Wrappers.<Copyright>lambdaQuery()
                .eq(Copyright::getId, copyrightDto.getId())
                .eq(Copyright::getStuId, copyrightDto.getStuId()));
        if(copyright==null){
            return Result.error(CommonConstants.DATASOURCE_IS_NULL);
        }
        synchronized ("updateCopyright"+CommonConstants.LOCK_INDEX+copyrightDto.getId()
                +CommonConstants.LOCK_INDEX+copyrightDto.getStuId()){
            //3、参数拷贝
            BeanUtils.copyProperties(copyrightDto,copyright);
            //4、进行修改
            int updateById = copyrightMapper.updateById(copyright);

            if(updateById==0){
                return Result.error(CommonConstants.UPDATE_FAIL);
            }

            //4、修改成功  修改CopyRightOwner表
            //4.1、修改CopyRightOwner表获取老旧信息
            List<String> oldCopyrightOwnerNames = copyrightOwnerMapper.getCopyrightOwnerName(copyrightDto.getId());

            //4.2、以防有重名人  用Map进行统计
            Map<String,Integer> oldCopyrightOwnerNameMap=new HashMap<>();
            for (String oldCopyrightOwnerName : oldCopyrightOwnerNames) {
                oldCopyrightOwnerNameMap.put(oldCopyrightOwnerName,oldCopyrightOwnerNameMap
                        .getOrDefault(oldCopyrightOwnerName,0)+1);
            }
            /*
            这里和前端商议好了 字符串传递  并商议好 "," 为分割
             */
            List<String> newCopyrightOwnerNames = ParseToListOrStringUtils.parseToListWithString(copyrightDto
                    .getCopyrightOwnerStr(), CopyrightConstants.COPYRIGHT_SPILT);
            copyrightDto.setCopyrightOwners(newCopyrightOwnerNames);
            //4、3同样将传入的数据进行转换成Map
            Map<String,Integer> newCopyrightOwnerNameMap=new HashMap<>();
            for (String newCopyrightOwnerName : newCopyrightOwnerNames) {
                newCopyrightOwnerNameMap.put(newCopyrightOwnerName,newCopyrightOwnerNameMap
                        .getOrDefault(newCopyrightOwnerName,0)+1);
            }

            //4、4  比较两个Map是否相等
            if(oldCopyrightOwnerNameMap.equals(newCopyrightOwnerNameMap)){
                return Result.success();
            }else{
                //4.5、不一样   图方便全部删除
                copyrightOwnerMapper.delete(Wrappers.<CopyrightOwner>lambdaQuery()
                        .in(CopyrightOwner::getCopyrightId,copyrightDto.getId())
                );
                //4.6、开始插入新的数据
                if(newCopyrightOwnerNames.size()==0){
                    return Result.success();
                }else{
                    for (String newCopyrightOwnerName : newCopyrightOwnerNames) {
                        CopyrightOwner copyrightOwner=new CopyrightOwner();
                        copyrightOwner.setStuId(copyrightDto.getStuId());
                        copyrightOwner.setCopyrightId(copyrightDto.getId());
                        copyrightOwner.setCopyrightOwnerName(newCopyrightOwnerName);

                        copyrightOwnerMapper.insert(copyrightOwner);
                    }
                }
            }
        }

        return Result.success();
    }
}
